/*
 * @Description:
 * @Author: chenju
 * @Date: 2022-01-12 16:22:42
 * @LastEditors: qingyang
 * @LastEditTime: 2023-05-06 17:02:29
 */
import { i18n } from '@/locales';
export * from './baseError';
import { weightUnitArr } from '@/constants/enum';
import { isObject } from 'lodash';
import Decimal from 'decimal.js';

export * from './format';

/**
 * @Description: 生成随机len位数字
 * @param {number} len 长度
 * @param {boolean} date 是否在结尾拼接当前日期 默认拼接
 * @return {string}
 */
export const randomLenNum = (len: number, date = true): string => {
  let random = '';
  random = Math.ceil(Math.random() * 100000000000000)
    .toString()
    .substr(0, len || 4);
  if (date) random = random + Date.now();
  return random;
};

/**
 * @Description: 将银行列表根据option转换
 * @param {any} bankList
 * @return {*}
 */
export const handleFormatBankOption = (bankList: any[]) => {
  const ans: any[] = [];
  for (const i in bankList) {
    const item: any = bankList[i];
    if (item.enableFlag) {
      ans.push({
        label: item.bankName,
        value: item.bankCode,
        option: item
      });
    }
  }
  return ans;
};

/**
 * @Description: 移除对象中的undefined元素
 * @param {any} params
 * @return {*}
 */
export const removeUndefinedParams = (params: any) => {
  const ans: any = {};
  for (const i in params) {
    if (typeof params[i] === 'undefined') {
      continue;
    }
    ans[i] = params[i];
  }
  return ans;
};

/**
 * 判断是否为空
 * @param value
 * @returns
 */
export const empty = (value: any): number | string => {
  if (typeof value === 'number') {
    return value;
  } else {
    return value || '-';
  }
};

/**
 * 判断字符串是否是json格式
 * @param str 字符串
 * @returns
 */
export function isJSON(str: string) {
  if (typeof str == 'string') {
    try {
      const obj = JSON.parse(str);
      if (typeof obj == 'object' && obj) {
        return true;
      } else {
        return false;
      }
    } catch (e) {
      // console.log('error：' + str + '!!!' + e);
      return false;
    }
  } else {
    console.error(`It is not a string!`);
  }
}

/**
 * 获取文件后缀名(小写字母)
 * @param filename 文件名
 * @returns
 */
export function getSuffix(filename: string) {
  if (filename.indexOf('.') > -1) {
    const filenameArr = filename.split('.');
    return filenameArr[filenameArr.length - 1].toLowerCase();
  } else {
    console.error('文件名不包含后缀！');
  }
}

/**
 * 保留数字的小数位数
 * @param number 输入值
 * @param digit 保留位数
 * @param canNegative 是否可以为负数
 * @param maxNumberAbs 最大的值的绝对值，传入0则不限制
 * @returns
 */
export function limitStrLength(
  value: unknown,
  digit = 0,
  canNegative = false,
  maxNumberAbs = 99999999
) {
  console.log('limitStrLength start', value);
  // 过滤非数字、字符串的输入
  if (typeof value !== 'string' && typeof value !== 'number') return '';
  // 过滤字符串空值
  if (typeof value === 'string' && value.trim() === '') return '';
  // 过滤最大值
  if (maxNumberAbs) {
    if (Number(value) > maxNumberAbs) return String(maxNumberAbs);
  }
  // 处理小数位数
  let res = Number(new Decimal(value).toFixed(Number(digit), Decimal.ROUND_DOWN));
  console.log('limitStrLength res', res);
  let isNegative = false;
  // 处理负数
  if (canNegative && res < 0) {
    isNegative = true;
  }
  res = Math.abs(res);
  const end = scienceToNumber(res);
  console.log('limitStrLength end', end, isNegative);
  return (isNegative ? '-' : '') + end;
}

//限制小数点后面位数
// export const limitStrLength = (
//   inputStr: any,
//   length = 0,
//   canNegative = false,
//   maxNumber = '99999999'
// ) => {
//   console.log('limitStrLength', inputStr);
//   if (Number.isNaN(Number.parseFloat(inputStr))) {
//     return '';
//   } else {
//     inputStr = Number.parseFloat(inputStr);
//   }
//   if (typeof inputStr === 'number') {
//     inputStr = String(inputStr);
//   }
//   console.log('limitStrLength 2', inputStr);
//   let negativeFlag = false;
//   // 表明是负数
//   if (canNegative && inputStr.includes('-')) {
//     inputStr = inputStr.replace(/^-/gi, '');
//     console.log('limitStrLength 负数 去掉负号', inputStr);
//     negativeFlag = true;
//   }
//   // 99999999999999为最大值
//   if (length !== undefined && String(inputStr).includes('.')) {
//     const arr = String(inputStr).split('.');
//     const integerStr = arr[0].length > maxNumber.length ? maxNumber : arr[0];
//     let str = arr[1];
//     if (length == 0) {
//       return integerStr;
//     }
//     if (str.length > 0 && str.length > length) {
//       str = str.substring(0, length);
//       inputStr = integerStr + '.' + str;
//     }
//   } else {
//     inputStr = inputStr.length > maxNumber.length ? maxNumber : inputStr;
//   }
//   if (canNegative) {
//     inputStr = (negativeFlag ? '-' : '') + inputStr;
//   } else {
//     inputStr = inputStr.replace(/-/g, '');
//   }
//   console.log('limitStrLength res', inputStr, negativeFlag);
//   return inputStr;
// };

export function scienceToNumber(val: number) {
  const e = String(val);
  const rex = /^([0-9])\.?([0-9]*)e-([0-9])/;
  if (!rex.test(e)) return String(val);
  const numArr = e.match(rex)!;
  const n = Number('' + numArr[1] + (numArr[2] || ''));
  const num = '0.' + String(Math.pow(10, Number(numArr[3]) - 1)).substr(1) + n;
  return num.replace(/0*$/, '');
}

/**
 * 保留小数点后位数，向下取整
 * @param num 要转变的数
 * @param n  保留位数
 * @returns
 */
export const tofixed = (num: number, n: number) => {
  if (typeof (num * 1) != 'number' || isNaN(num * 1)) return '-';
  const strNum = String(num);
  if (strNum.includes('.')) {
    const arr = strNum.split('.');
    return Number(arr[0] + '.' + arr[1].substring(0, n));
  }
  return num;
};

// kg->t单位转化
export const renderResultUnit = (num: number | any, unitSuffix = ' CO₂e', digit?: number) => {
  if (typeof (num * 1) != 'number' || isNaN(num * 1)) return '-';
  return justRenderResultValue(num, digit) + ' ' + justRenderResultUnit(num, unitSuffix);
  // if (num >= 1000) {
  //   return parseFloat(new Decimal(num).div(new Decimal(1000)).toNumber().toFixed(5)) + ' t CO₂e';
  // } else if (num >= 1) {
  //   // return tofixed(num, 3) + ' kg CO₂e';
  //   return parseFloat(num.toFixed(3)) + ' kg CO₂e';
  // } else if (num === 0) {
  //   return num + ' CO₂e';
  // } else if (num <= -1000) {
  //   // 小于-1000
  //   return parseFloat(new Decimal(num).div(new Decimal(1000)).toNumber().toFixed(5)) + ' t CO₂e';
  // } else if (num < 1) {
  //   // 小于1取g
  //   // return tofixed(num * 1000, 2) + ' g CO₂e';
  //   return parseFloat(new Decimal(num).mul(new Decimal(1000)).toNumber().toFixed(2)) + ' g CO₂e';
  // }
  // // 小于0 大于 -1000
  // // return tofixed(num, 3) + ' kg CO₂e';
  // return parseFloat(num.toFixed(3)) + ' kg CO₂e';
};

/**
 * 只加载单位
 * @param num
 * @returns
 */
export const justRenderResultUnit = (num: number, unitSuffix = ' CO₂e') => {
  if (num >= 1000 || num <= -1000) {
    return `t${unitSuffix}`;
  } else if (num !== 0 && num < 1) {
    return `g${unitSuffix}`;
  } else {
    return `kg${unitSuffix}`;
  }
};
/**
 * 只加载数值
 * @param num
 * @param dight 统一的小数位数
 * @returns
 */
export const justRenderResultValue = (num: number, dight?: number) => {
  if (typeof (num * 1) != 'number' || isNaN(num * 1)) return '-';
  let str;
  if (num >= 1000 || num <= -1000) {
    // return tofixed(num / 1000, 5);
    str = new Decimal(num)
      .div(new Decimal(1000))
      .toNumber()
      .toFixed(dight ?? 5);
  } else if (num === 0) {
    return num;
  } else if (num < 1) {
    str = new Decimal(num)
      .mul(new Decimal(1000))
      .toNumber()
      .toFixed(dight ?? 0);
  } else {
    str = (num * 1).toFixed(dight ?? 3);
  }
  return parseFloat(str);
};

/**
 * 只kg转T
 * @param num
 * @returns
 */
export const kgToT = (num: number) => {
  return parseFloat(new Decimal(num).div(new Decimal(1000)).toNumber().toFixed(5));
  // return tofixed(num / 1000, 5);
};

/**
 * 根据值获取数组中的名称
 * @param targetArr 目标数组
 * @param value 值
 * @param valueKey 数组的value键名
 * @param nameKey 数组的name键名
 * @returns
 */
export function getNameByValue(
  targetArr: any[],
  value: any,
  valueKey = 'value',
  nameKey = 'label'
) {
  const index = targetArr.findIndex(n => n[valueKey] === value);
  if (index > -1) {
    return targetArr[index][nameKey];
  }
  return null;
}

/**
 * 格式化成百分比
 * @param num
 * @param symbol
 * @returns
 */
export function rateFormat(num: number | string | undefined | null, digit = 2, symbol = '%') {
  if (num === undefined || num === null) return '-';
  if (empty(num) === '-') return '-';
  if (typeof num === 'string') {
    num = Number(num);
  }
  return Number((num * 100).toFixed(digit)) + symbol;
}

/**
 * 获取当前url地址（不含路径）
 * @returns
 */
export const getLocationOrigin = () => {
  if (!window.location.origin) {
    return (
      window.location.protocol +
      '//' +
      window.location.hostname +
      (window.location.port ? ':' + window.location.port : '')
    );
  }
  return window.location.origin;
};

// 去除文件的后缀名
export function hideFileSuffix(fileName: string | null) {
  if (fileName && fileName.lastIndexOf('.') > -1) {
    return fileName.slice(0, fileName.lastIndexOf('.'));
  } else {
    return empty(fileName);
  }
}

// 单位是否是重量单位
export function isWeightUnit(unit: undefined | string) {
  if (typeof unit === 'string' && unit) {
    return !!weightUnitArr.includes(unit);
  } else {
    return false;
  }
}

//限制小数点后面位数
export const limitLength = (inputStr: string, length?: number) => {
  // 99999999999999为最大值
  if (length !== undefined && String(inputStr).includes('.')) {
    const arr = String(inputStr).split('.');
    const parseStr = parseInt(arr[0], 10).toString();
    const integerStr = parseStr.length > 14 ? '99999999999999' : parseStr;
    let str = arr[1];
    if (length == 0) {
      // 取整
      return integerStr;
    }
    if (str.length > 0 && str.length > length) {
      str = str.substring(0, length);
    }
    inputStr = integerStr + '.' + str;
  } else {
    inputStr = parseInt(inputStr, 10).toString();
    inputStr = inputStr.length > 14 ? '99999999999999' : inputStr;
  }
  return inputStr;
};

// 判断某个值是否存在数组中的某个对象中
export const isRepeat = (value: any, arr: any) => {
  let tmp = 0;
  for (const i in arr) {
    if (value === arr[i].code) {
      tmp += 1;
    }
  }
  return tmp;
};

export function fixZero(value: any) {
  if (value === '-') {
    return value;
  }
  const arrayNum = value.toString().split('.');
  if (arrayNum.length == 1) {
    return value.toString() + '.00';
  }
  if (arrayNum.length > 1) {
    if (arrayNum[1].length < 2) {
      return value.toString() + '0';
    } else {
      return value;
    }
  }
}

// kg->t单位转化, 保留六位
export const formatKgToT = (num: any) => {
  const typeofNum = typeof num;
  if (typeofNum === 'undefined' || num === null || num === '') {
    return '-';
  }
  return tofixed(num / 1000, 6);
};

/**
 * 根据分隔符号返回i18n的名称
 * @param str 需要翻译的字符串
 * @param moduleName 所属的i18n对应模块
 * @param separator 带翻译字符串的分隔符
 * @param resSeparator 翻译后字符串的分隔符
 * @returns string
 */
export function getI18nNameBySeparator(
  str: string,
  moduleName: string,
  separator = ',',
  resSeparator = '、'
) {
  let resStr = '';
  if (str) {
    str.split(separator).forEach(item => {
      resStr += (resStr ? resSeparator : '') + i18n.global.t(`${moduleName}.${item}`);
    });
    return resStr;
  } else {
    return '-';
  }
}

export function getNameBySeparator(
  name: string,
  str: string,
  moduleName: string,
  separator = ',',
  resSeparator = '、'
) {
  let resStr = '';
  if (str) {
    str.split(separator).forEach(item => {
      resStr += (resStr ? resSeparator : '') + i18n.global.t(`${moduleName}.${item}`);
    });
    return name + resStr;
  } else {
    return '-';
  }
}

/**
 * 获取i18n的翻译名称，过滤空
 * @param str 和$t一样的传值
 * @returns
 */
export function getI18nName(str: string) {
  if (!str) {
    return '-';
  } else if (str.includes('.')) {
    const last = str.split('.').pop();
    if (last === 'null' || last === 'undefined' || last === '') {
      return '-';
    }
  }
  return i18n.global.t(`${str}`);
}
export const fixedInit = () => {
  // 重写toFixed原型链四舍五入
  Number.prototype.toFixed = function (len: number) {
    let result = Decimal.div(
      Math.round(Decimal.mul(Math.pow(10, len), this as number).toNumber()),
      Math.pow(10, len)
    ).toString();
    // 补0
    if (result.indexOf('.') == -1) {
      if (len != 0) {
        result += '.';
        result += new Array(len + 1).join('0');
      }
    } else {
      const arr = result.split('.');
      if (arr[1].length < len) {
        arr[1] += new Array(len - arr[1].length + 1).join('0');
      }
      result = arr.join('.');
    }
    return result;
  };
};

// 将File格式转为base64
export function getBase64ByFileSync(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    let imgResult = '';
    reader.readAsDataURL(file);
    reader.onload = function () {
      imgResult = reader.result as string;
    };
    reader.onerror = function (error) {
      reject(error);
    };
    reader.onloadend = function () {
      resolve(imgResult);
    };
  });
}

/**
 * 将object的value转成数组
 * @param obj
 * @returns string[]
 */
export function transformObjectToValueList(obj: { [key: string]: string }): string[] {
  if (!isObject(obj)) return [];
  const arr = [];
  for (const i in obj) {
    arr.push(obj[i]);
  }
  return arr;
}

/**
 * 将object的key转成数组
 * @param obj
 * @returns string[]
 */
export function transformObjectToKeyList(obj: { [key: string]: string }): string[] {
  if (!isObject(obj)) return [];
  const arr = [];
  for (const i in obj) {
    arr.push(i);
  }
  return arr;
}

/**
 * 将object的value转成字符串
 * @param obj
 * @param separator
 * @returns string
 */
export function transformObjectToValueStr(obj: { [key: string]: string }, separator = ''): string {
  if (!isObject(obj)) return '';
  const arr = transformObjectToValueList(obj);
  return arr.join(separator || '');
}

/**
 * 四舍五入将kg单位数值转成t并保留小数
 * @param num 值
 * @param digit 小数位数
 * @returns
 */
export function transformUnitKgToT(num: any, digit = 5): number | '-' {
  const typeofNum = typeof num;
  if (typeofNum === 'undefined' || num === null || num === '') {
    return '-';
  }
  if (typeofNum !== 'string' && typeofNum !== 'number') {
    return '-';
  }
  if (typeofNum === 'string') {
    num = Number(num);
    if (isNaN(num)) {
      return '-';
    }
  }
  return num === 0 ? 0 : Number((num / 1000).toFixed(digit));
  // return num === 0 ? 0 : Math.floor((num / 1000) * Math.pow(10, digit)) / Math.pow(10, digit);
}

/**
 * 四舍五入保留小数
 * @param num 值
 * @param digit 小数位数
 * @returns
 */
export function numberFormat(num: any, digit = 5): number | '-' {
  const typeofNum = typeof num;
  if (typeofNum === 'undefined' || num === null || num === '') {
    return '-';
  }
  if (typeofNum !== 'string' && typeofNum !== 'number') {
    return '-';
  }
  if (typeofNum === 'string') {
    num = Number(num);
    if (isNaN(num)) {
      return '-';
    }
  }
  return num === 0 ? 0 : Number(num.toFixed(digit));
  // return num === 0 ? 0 : Math.floor(num * Math.pow(10, digit)) / Math.pow(10, digit);
}

/**
 * 气体转化
 * @param gas
 * @param brackets 是否加括号
 * @returns
 */
export const renderGas = (gas: string, brackets = true) => {
  const gasEnums: any = {
    CO2: 'CO₂',
    CH4: 'CH₄',
    N2O: 'N₂O',
    'HFCs/PFCs': 'HFCs/PFCs',
    SF6: 'SF₆',
    NF3: 'NF₃'
  };
  const gasItem = gasEnums[gas] ? gasEnums[gas] : gas;
  return gasItem.includes('/') && brackets ? `(${gasItem})` : gasItem;
};

/**
 * 格式化盘查周期
 * @param inventoryYear
 * @param isDetailFormat 是否是详细格式（带年月的）
 * @returns
 */
export function formatTaskInventoryYearName(inventoryYear: string, isDetailFormat = false) {
  if (!inventoryYear) return '-';
  if (inventoryYear.length === 4) return inventoryYear + (isDetailFormat ? '年' : '');
  if (inventoryYear.length === 6) {
    const res =
      inventoryYear.slice(0, 4) +
      (isDetailFormat ? '年' : '-') +
      inventoryYear.slice(4, 6) +
      (isDetailFormat ? '月' : '');
    return res;
  }
  return empty(inventoryYear);
}

/**
 * 千分位
 * @param value
 * @returns string
 */
export const thousandFormat = (value: number | string): string => {
  if (empty(value) == '-') return '-';
  if (value.toString().includes('.')) {
    const parts = value.toString().split('.');
    parts[0] = parts[0].replace(/(\d)(?=(\d{3})+\b)/g, function ($1, $2) {
      return $2 + ',';
    });
    return parts.join('.');
  }
  return value.toString().replace(/(\d)(?=(\d{3})+\b)/g, function ($1, $2) {
    return $2 + ',';
  });
};

/**
 * 将时间去掉time
 * @param dateStr
 * @returns string
 */
export const delTime = (dateStr: string) => {
  const arr = dateStr.split(' ');
  if (arr.length) {
    return arr[0];
  }
  return empty(dateStr);
};

/**
 * 跳转到报错的位置
 * @param container 父容器的class｜id
 * @param error 错误的class｜id
 */
export function handleScrollToErrorPosition(container: string, error = '.is-error') {
  // 跳转到报错的位置
  const warningSectionEl: HTMLElement | null = document.querySelector(error);
  const containerEl: HTMLElement | null = document.querySelector(container);
  if (containerEl && warningSectionEl) {
    scrollIntoView(containerEl, warningSectionEl);
  }
}

/**
 * @Description: 跳转到指定dom的位置
 * @param {*} container 父容器
 * @param {*} selected  要跳转dom
 * @return {*} null
 */
export function scrollIntoView(container: HTMLElement, selected: HTMLElement): void {
  console.log('scrollIntoView', container, selected);
  const offsetParents: HTMLElement[] = [];
  let pointer = selected.offsetParent;
  while (pointer !== null && container !== pointer && container.contains(pointer)) {
    offsetParents.push(pointer as HTMLElement);
    pointer = (pointer as HTMLElement).offsetParent;
  }
  const top = selected.offsetTop + offsetParents.reduce((prev, curr) => prev + curr.offsetTop, 0);
  const bottom = top + selected.offsetHeight;
  const viewRectTop = container.scrollTop;
  const viewRectBottom = viewRectTop + container.clientHeight;
  if (top < viewRectTop) {
    container.scrollTop = top;
    window.scrollTo(0, top);
  } else if (bottom > viewRectBottom) {
    container.scrollTop = bottom - container.clientHeight;
    window.scrollTo(0, bottom - container.clientHeight);
  } else {
    // 从相对位置再向下偏移100px
    window.scrollTo(0, top - 100);
  }
}

export function deepMerge<T = any>(src: any = {}, target: any = {}): T {
  let key: string;
  for (key in target) {
    src[key] = isObject(src[key]) ? deepMerge(src[key], target[key]) : (src[key] = target[key]);
  }
  return src;
}

/**
 * 从树结构中找到对象
 * @param tree 树结构
 * @param conditionFn  过滤方法如：(node) => node.id === 'your id')
 */
export function findItemInTree<T = any>(tree: any[], conditionFn: Fn): T | undefined {
  for (let i = 0; i < tree.length; i++) {
    if (conditionFn(tree[i])) {
      return tree[i]; // 如果当前节点满足条件，返回当前节点
    }
    if (tree[i].children) {
      const found = findItemInTree(tree[i].children, conditionFn); // 递归搜索子节点

      if (found) {
        return found; // 如果在子节点中找到，返回找到的节点
      }
    }
  }
}

/**
 * 获取超出字数行数的文本，并给增加换行和省略号
 * @param value
 * @param options
 * @returns
 */
export function getValueOverflow(
  value: string,
  options?: { wordsInALine?: number; lineNum?: number; suffixSymbol?: string; symbolWords?: number }
) {
  const { wordsInALine = 4, lineNum = 1, suffixSymbol = '...', symbolWords = 1 } = options || {};
  let val = value;
  let res = '';
  let num = lineNum;
  while (num) {
    let lineWords = val;
    if (val.length > wordsInALine) {
      lineWords = val.slice(0, wordsInALine);
      val = val.slice(wordsInALine);
    } else {
      val = '';
    }
    res += lineWords;
    num--;
    if (num > 0) {
      res += '\n';
    }
  }
  if (val.length && suffixSymbol) {
    res = res.slice(0, Math.floor(symbolWords * -1)) + suffixSymbol;
  }
  return res;
}
